Jinja2基础使用
层级关系
flask_test |__templates | |__index.html |__app.py
index.html
{ {user.user}} return{ {user.user}}
{% if user.burs %} { {user.burs}} {% else %} 233333 {% endif %}
- {% for mouv in mours %}
- { {mouv.name}}--{ {mouv.year}} {% endfor %}
app.py
#!/usr/bin/env python# -*- coding: utf-8 -*-from flask import Flask, request, render_template,render_template_stringfrom jinja2 import escape"""html字符实体转义:https://dev.w3.org/html5/html-author/charrefjinja2使用 语法 语句 if判断 for循环 ==》 {% --- %} 表达式 字符串、变量、函数调用 ==》 { { --- }} PS 获取变量属性 ==》. [例:user.username] 允许使用 对象:字符串、列表、字典、元组、整型、浮点型、布尔值 运算符:+、 -、 *、 / 比较符号:==、 != 逻辑符号:and or not in is None 布尔值 示例: user={'user':'gg','burs':'you love'} mours = [{'name':1,'year':"ss"},{'name':2,'year':"uu"}] if判断: {% if user.burs %} { {user.burs}} {% else %} 233333 {% endif %} # 需要有endif做结尾 for循环:[http://jinja.pocoo.org/docs/2.10/templates/#for]==>for循环相关
- {% for mouv in mours %}
- { {mouv.name}}--{ {mouv.year}} {% endfor %} # 需要有endfor做结尾
hello {}
'.format(escape(name))@app.route('/templates')def templates(): """ render_template() 渲染函数 render_template_string() 用来渲染模板字符串 PS:传入的jinja2的变量值可以是字符串、列表、和字典,也可以是函数、类和类实例 实例:这是列表mylist第一个元素{
{ mylist[0] }}这是元组mytuple第一个元素{
{ mytuple[0] }}这是字典mydict第一个元素{
{ mydict["name"] }}这是函数myfunc的返回值{
{ myfunc() }}这是对象myobject的调用某个方法返回值{
{ myobject.name() }} :return: """ user = { 'user': 'gg', 'burs': 'you love'} mours = [{ 'name': 1, 'year': "ss"}, { 'name': 2,'year': "uu"}] return render_template('templations.html', user=user, mours=mours)if __name__ == '__main__': app.run()Jinja2上下文
#!/usr/bin/env python# -*- coding: utf-8 -*-from flask import Flask, request, render_template,render_template_string,url_for,get_flashed_messagesfrom jinja2 import escape"""上下文 1、变量 模板上下文包含了很多变量,其中包括我们调用render_template()函数时手动传入的变量以及Flask默认传入的变量。 除了渲染时传入变量,你也可以在模板中定义变量,使用set标签: {% set navigation = [('/', 'Home'),('/about', 'About')] %} 也可以将一部分模板定义成变量,使用set和enfset标签声明 {% set navigation %} Home About {% endset %} 2、标准模板全局变量 config 当前的配置对象 request 当前的请求对象,在已经激活的请求环境中可用 session 当前的回话对象,在已经激活的请求环境中可用 g 与请求绑定的全局变量,在已经激活的请求环境中可用 3、自定义上下文 app.context_processor装饰器 4、全局对象 在所有模板中都可以使用的对象 1、内置全局函数 A:jianja2模板中内置全局函数【常见】==》jianja2模板中内全量全局函数列表链接 http://jinja.pocoo.org/docs/2.10/templates/#list-of-global-functions range([start,]stop[,stop]) 和python中的range()用法相同 lipsum(n=5, html=True, min=20, max=100) 生成随机文本默认为5段html文本,每段包含20到100字符 dict(**items) 和python中的dict()用法相同 B:Flask内置模板全局函数 url_for() 用于生成url的函数 例:return get_flashed_messages() 用于获取flask消息的函数 2、自定义全局函数 """app = Flask(__name__)@app.context_processordef inject_foo_one(): """ 原理: 如果多个模板都需要使用同一变量,那么比起在多个视图函数中重复传入,更好的方法是能够设置一个模板全局变量。 Flask提供了一个app.context_processor装饰器,可以用来注册模板上下文处理函数,它可以帮我们完成统一传入变量的工作。 模板上下文处理函数需要返回一个包含变量键值对的字典 html中调用方法:{ {foo}}
使用方式 第一种:函数inject_foo_one 第二种:函数inject_foo_two 第三种:使用lambda简化成 @app.context_processor(lambda: dict(foos='inject_foo_three')) :return: """ foo = 'I am inject_foo' return dict(foo=foo)def inject_foo_two(): """方法二""" foot = 'inject_foo_two' return dict(foot=foot)@app.context_processor(inject_foo_two)@app.route('/escape')def escape_index(): """escape:用于安全转义""" name = request.args.get('name') return 'hello {}
'.format(escape(name))@app.route('/templates')def templates(): """ """ user = { 'user': 'gg', 'burs': 'you love'} mours = [{ 'name': 1, 'year': "ss"}, { 'name': 2,'year': "uu"}] return render_template('templations.html', user=user, mours=mours)@app.template_global()def bar(): """ 除了使用app.context_processor注册模板上下文处理函数来传入函数,也可以使用app.template_global装饰器直接将函数注册为模板全局函数 PS:默认使用函数的原名称传入模板,在@app.template_global()装饰器使用name参数可以指定一个自定义名称 @app.add_template_global("name") ==> 注册自定义全局函数,传入函数对象可选的自定义名称 :return: """ return 'I bar'if __name__ == '__main__': app.run()
过滤器
#!/usr/bin/env python# -*- coding: utf-8 -*-from flask import Flask,render_templatefrom flask import Markupfrom jinja2 import escape"""过滤器 在Jinja2中,过滤器(filter)是一些可以用来修改和过滤变量值的特殊函数,过滤器和变量用一个竖线(管道符号)隔开, 需要参数的过滤器可以像函数一样使用括号传递。 例: { { name|title }} ==> python中的name.title { { movies|length }} ==> python中的len(movies) 另一种使用方法 将过滤器作用于一部分模板数据,使用filter标签和endfilter标签声明开始和结束 {% filter upper %} over upper {% endfilter %} 常用内置过滤器 default(value, default_value=u", boolean=False) 设置默认值,默认值作为参数传入,别名为d escape(s) 转义html文本,别名为e first(seq) 返回序列的第一个元素 last(seq) 返回序列的最后一个元素 length(object) 返回变量的长度 random(seq) 返回序列中的随机元素 safe(value) 将变量值标记为安全,避免转义 trim(value) 清除变量值前后的空格 max(value, case_sensitive=False,attribute=None) 返回序列中的最大值 min(value, case_sensitive=False,attribute=None) 返回序列中的最小值 unique(value, case_sensitive=False,attribute=None) 返回序列中的不重复值 striptags(value) 清除变量值内的html标签 urlize(value, trim_url_limit=None, nofollow=False, target=None, rel=None) 将url文本转换为可单击的html链接 wordcount(s) 计算单词数量 tojson(value, indent=None) 将变量值转化为json格式 truncate(s, length=255, killwords=False, end='...', leeway=None) 截断字符串,常用于显示文章摘要,length参数设置截断的长度, killwords参数设置是否截断单词,end参数设置结尾的符号 全量内置过滤器链接 http://jinja.pocoo.org/docs/2.10/templates/#builtin-filters 过滤器叠加使用用例{ {name|default('默认人')|title}} ==> 将name变量设置默认值,并同时标题化 传输文本消毒方式 """app = Flask(__name__)@app.route('/index')def index(): """ 文本传输消毒方式 方式一 escape()函数对变量进行转义 方式二 from flask import Markup ps:在文本中可以直接使用{ {text}} :return: """ text = Markup("HELLO FLASK
") return render_template('index.html', text=text)@app.template_filter()def Disinfect(s): """ 自定义过滤器 和注册全局函数类似,可以在app.template_filter()中使用name关键字设置过滤器的名称,默认会使用函数名称。 过滤器函数需要接收被处理的值作为输入,返回处理后的值。过滤器函数接收s作为被过滤的变量值,返回处理后的值。 创建的 Disinfect过滤器会在被过滤的变量字符后面添加一个音符图标,因为音符通过HTML实体♫表示, 使用 Markup类将它标记为安全字符。在使用时和其他过滤器用法相同 { { name|Disinfect }} ps:可以直接使用app.add_template_filter() 方法注册自定义过滤器,传入函数对象和可选的自定义名称(name) 例:app.add_template_filter(your_filter_function) :param s: :return: """ return s + Markup(' ♫')if __name__ == '__main__': app.run()
测试器
#!/usr/bin/env python# -*- coding: utf-8 -*-from flask import Flask"""测试器 内置测试器 全量内置测试器:http://jinja.pocoo.org/docs/2.10/templates/#list-of-builtin-tests 使用: 在使用测试器时,is的左侧是测试器函数的第一个参数(value),其他参数可以添加括号传入,也可以在右侧使用空格连接 {% if foo is sameas(bar) %} == {% if foo is sameas bar %} 自定义测试器 """app = Flask(__name__)@app.template_test()def baz(z): """ 自定义测试器 使用template_test装饰器来注册一个自定义测试器 PS:也可以使用add_template_test() 方法来注册自定义测试器,传入函数对象和可选的自定义名称 例 @app.add_template_test(baz,name='baz') :param s: :return: """ if z == 'baz': return True return Falseif __name__ == '__main__': app.run()
Environment类
#!/usr/bin/env python# -*- coding: utf-8 -*-from flask import Flaskimport jinja2"""在Jinja2中,渲染行为由jinja2.Environment类控制,所有的配置选项、上下文变量、全局函数、过滤器和测试器都存储在Environment实例上"""jinja2.Environment()"""例:各种字符定义block_start_string=BLOCK_START_STRING,block_end_string=BLOCK_END_STRING,variable_start_string=VARIABLE_START_STRING,variable_end_string=VARIABLE_END_STRING,comment_start_string=COMMENT_START_STRING,comment_end_string=COMMENT_END_STRINGBLOCK_START_STRING = '{%'BLOCK_END_STRING = '%}'VARIABLE_START_STRING = '{ {'VARIABLE_END_STRING = '}}'COMMENT_START_STRING = '{#'COMMENT_END_STRING = '#}'"""# 当jinja2与Flask结合后,便不再单独创建Environment对象了,而是使用Flask创建的Environment对象,存储在app.jinja_env属性上app = Flask(__name__)# 修改标记注释结尾的字符串app.jinja_env.comment_end_string = '[['"""模板环境中的全局函数、过滤器和测试器分别存储在 Environment对象的 globals、 filters和 tests属性中,这三个属性都是字典对象。除了使用Flask提供的装饰器和方法注册自定义函数,也可以直接操作这三个字典来添加相应的函数或变量,这通过向对应的字典属性中添加一个键值对实现,传入模板的名称作为键,对应的函数对象或变量作为值。"""# 示例:添加自定义全局对象,此与app.template_global()装饰器不同,直接操作global字典允许传入任意python对象text1 = "one to one"def fun(): return "func"app.jinja_env.globals["text1"] = text1app.jinja_env.globals["fun"] = fun# 添加自定义过滤器def func(s): return s + "@+@"app.jinja_env.filters["func"] = func# 添加自定义测试器def funct(n): if n == "a": return True return Falseapp.jinja_env.tests["funct"] = funct# 全量 Environment对象方法 http://jinja.pocoo.org/docs/latest/api/#jinja2.Environment